package se.id.vrapp;

import java.util.Locale;
import java.util.Random;

import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.PowerManager;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

public class VRappActivity extends FragmentActivity implements
		SensorEventListener, OnInitListener {
	static final int NUM_ITEMS = 4;
	MyAdapter mAdapter;
	ViewPager mPager;

	private SensorManager mSensorManager;
	private Sensor mLinearAccelerometer;

	private TextToSpeech speech;

	private AsyncTask strikeMenu;

	private static int sensitivity;
	private int counter, index, menuItem;
	private long cooldown, curTime;
	private float[] recent;
	private float threshold, avg;
	private MediaPlayer mp;

	private Random random;
	private String[] speechLines = { "Go faster you fat bastard!",
			"I felt that", "Ouch, stop fucking hitting me!",
			"Oh yeah, smack me hard", "Damn, that hurt!",
			"Hit me, see if I care", "Well, fuck you too!",
			"That's not very nice!", "What the...",
			"What do you want from me?", "Getting real tired of your shit!",
			"What is your major malfunction?", "Hooray for boobies!" };

	// private MediaPlayer mp;

	private PowerManager.WakeLock mWakeLock;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main_pager);
		final ActionBar actionBar = getActionBar();

		// Specify that tabs should be displayed in the action bar.
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

		mAdapter = new MyAdapter(getSupportFragmentManager());

		mPager = (ViewPager) findViewById(R.id.pager);
		mPager.setAdapter(mAdapter);
		mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
			@Override
			public void onPageSelected(int position) {
				// When swiping between pages, select the
				// corresponding tab.
				getActionBar().setSelectedNavigationItem(position);
			}
		});

		// Create a tab listener that is called when the user changes tabs.
		ActionBar.TabListener tabListener = new ActionBar.TabListener() {
			public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
				// show the given tab
				mPager.setCurrentItem(tab.getPosition());
			}

			public void onTabUnselected(ActionBar.Tab tab,
					FragmentTransaction ft) {
				// hide the given tab
			}

			public void onTabReselected(ActionBar.Tab tab,
					FragmentTransaction ft) {
				// probably ignore this event
			}
		};
		// Add 3 tabs, specifying the tab's text and TabListener
		actionBar.addTab(actionBar.newTab().setText("Plan race")
				.setTabListener(tabListener), 0, false);
		actionBar.addTab(
				actionBar.newTab().setText("Map").setTabListener(tabListener),
				1, true);
		actionBar.addTab(
				actionBar.newTab().setText("Status")
						.setTabListener(tabListener), 2, false);
		actionBar.addTab(
				actionBar.newTab().setText("Friends")
						.setTabListener(tabListener), 3, false);

		mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		mLinearAccelerometer = mSensorManager
				.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);

		random = new Random();

		threshold = 0;
		counter = 0;
		cooldown = 0;
		avg = 0;
		menuItem = 0;
		recent = new float[10];
		for (int i = 0; i < recent.length; i++) {
			recent[i] = 5;
		}
		index = 0;
		mp = MediaPlayer.create(getBaseContext(), R.raw.diding);
		sensitivity = 5;
		curTime = System.currentTimeMillis();

		speech = new TextToSpeech(this, this);

		PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
		mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
		mWakeLock.acquire();
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK) {
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu items for use in the action bar
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.layout.menu_action_bar, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle presses on the action bar items
		switch (item.getItemId()) {
		case R.id.action_setting:
			// Set the settings view that should be shown! change the class...
			Intent intent = new Intent(this, SettingsActivity.class);
			startActivity(intent);

			return true;
		case R.id.action_audio_order:
			// Set the settings view that should be shown! change the class...
			Intent intent2 = new Intent(this, AudioMenuOrderActivity.class);
			startActivity(intent2);

			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	public static class MyAdapter extends FragmentPagerAdapter {
		public MyAdapter(FragmentManager fm) {
			super(fm);
		}

		@Override
		public int getCount() {
			return NUM_ITEMS;
		}

		@Override
		public Fragment getItem(int position) {
			if (position == 0)
				return PlanRaceFragment.newInstance(position);
			else if (position == 1)
				return MapFragment.newInstance(position);
			else if (position == 2)
				return StatusFragment.newInstance(position);
			else
				return FriendsFragment.newInstance(position);
		}
	}

	@Override
	public final void onAccuracyChanged(Sensor sensor, int accuracy) {
		// Do something here if sensor accuracy changes.
	}

	@Override
	public final void onSensorChanged(SensorEvent event) {
		curTime = System.currentTimeMillis();
		if (event.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION) {
			avg = 0;
			for (int i = 0; i < recent.length; i++) {
				avg += recent[i];
			}
			avg = avg / recent.length;
			float x = Math.abs(event.values[0]);
			float y = Math.abs(event.values[1]);
			float z = Math.abs(event.values[2]) * 1.1f;
			if (curTime > cooldown) {
				threshold = (avg + 8 - sensitivity) * 3.0f;
				if ((x + y + z) > threshold && (x + y + z) > 2.5f) {
					strike();
				} else {
					recent[index] = x + y + z;
					if (index >= recent.length - 1)
						index = 0;
					else
						index++;
				}
			}
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		mSensorManager.registerListener(this, mLinearAccelerometer,
				SensorManager.SENSOR_DELAY_GAME);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
	}

	@Override
	protected void onPause() {
		super.onPause();
		// mSensorManager.unregisterListener(this);
	}

	protected void strike() {
		// counter++;
		// speak();
		// mp.start();
		menuItem++;
		strikeMenu = new StrikeMenu().executeOnExecutor(
				AsyncTask.THREAD_POOL_EXECUTOR, menuItem);
		cooldown = curTime + 700;
		Log.e("Strike()", "A strike was registered!");
	}

	private void speakMenu(int number) {
		// String text = speechLines[random.nextInt(speechLines.length)];
		String text = "";
		if (number == 1) {
			text = "status";
		} else if (number == 2) {
			text = "next depot";
		} else if (number == 3) {
			text = "friends";
		} else if (number == 4) {
			text = "personal goal";
		} else
			text = "cancelled";
		speech.speak(text, TextToSpeech.QUEUE_FLUSH, null);
	}

	private void speak(int number) {
		String text = "";
		if (number == 1) {
			text = "You have travelled " + random.nextInt(300) + "km in "
					+ random.nextInt(17) + " hours and " + random.nextInt(59) + " minutes";
		} else if (number == 2) {
			text = "next depot is in Grennah, where you can eat a hot meal get something to drink and use the bathroom";
		} else if (number == 3) {
			text = "Ehkis is ten hours behind you and not likely to finish the race, Kais-ah just finished with a total time of eleven hours.";
		} else if (number == 4) {
			text = "You should speed up to meet your personal goal";
		} else
			text = "This is the readout of menu item number " + number;
		speech.speak(text, TextToSpeech.QUEUE_FLUSH, null);
	}

	@Override
	public void onInit(int status) {
		if (status == TextToSpeech.SUCCESS) {

			int result = speech.setLanguage(Locale.US);

			if (result == TextToSpeech.LANG_MISSING_DATA
					|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
				Log.e("TTS", "This Language is not supported");
			} else {
			}

		} else {
			Log.e("TTS", "Initilization Failed!");
		}
	}

	private class StrikeMenu extends AsyncTask<Integer, Void, Integer> {

		// private int myValue;

		@Override
		protected Integer doInBackground(Integer... myValue) {
			// this.myValue = myValue[0];
			mp.start();
			try {
				Thread.sleep(500);
				speakMenu(myValue[0]);
				Log.e("doInBackground", "Entering waiting!");
				if (myValue[0] < 5)
					Thread.sleep(2300);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			Log.e("doInBackground", "Done waiting!");
			return myValue[0];
		}

		protected void onPostExecute(Integer myValue) {
			if (myValue > 4) {
				menuItem = 0;
			} else if (menuItem == myValue) {
					cooldown = curTime + 4000;
					Log.e("onPostExecute", "Reading menu # " + myValue
							+ ". Sens is: " + sensitivity);
					menuItem = 0;
					speak(myValue);
					menuItem = 0;
			} else
				Log.e("onPostExecute", "No readout");
		}
	}

	public static void setSensitivity(int s) {
		sensitivity = s;
	}
}
